#include "Vector.h"
#include <cmath>

Vector3::Vector3()
{		
}
Vector3::Vector3(const Vector3 &vector)
{
	x = vector.x;
	y = vector.y;
	z = vector.z;
}
Vector3::Vector3(real x, real y, real z)
{
	this->x = x;
	this->y = y;
	this->z = z;
}

Vector3::Vector3(const Vector2 &vector)
{
	x = vector.x;
	y = vector.y;
	z = 0;
}
Vector3& Vector3::operator = (Vector3 &v)
{
	x = v.x;
	y = v.y;
	z = v.z;
	return *this;
}
Vector3 operator + (Vector3 &v1, Vector3 &v2)
{
	Vector3 v;
	v.x = v1.x + v2.x;
	v.y = v1.y + v2.y;
	v.z = v1.z + v2.z;
	return v;
}

Vector3 operator - (Vector3 &v1, Vector3 &v2)
{
	Vector3 v;
	v.x = v1.x - v2.x;
	v.y = v1.y - v2.y;
	v.z = v1.z - v2.z;
	return v;
}
Vector3& Vector3::operator += (Vector3 &v)
{
	x += v.x;
	y += v.y;
	z += v.z;
	return *this;
}
Vector3& Vector3::operator -= (Vector3 &v)
{
	x -= v.x;
	y -= v.y;
	z -= v.z;
	return *this;
}

Vector3& Vector3::operator *= (real value)
{
	x *= value;
	y *= value;
	z *= value;
	return *this;
}
Vector3& Vector3::operator /= (real value)
{
	x /= value;
	y /= value;
	z /= value;
	return *this;
}
Vector3 operator * (Vector3 &v, real value)
{
	Vector3 nv(v);
	nv.x *= value;
	nv.y *= value;
	nv.z *= value;
	return nv;
}
Vector3 operator * (real value, Vector3 &v)
{
	Vector3 nv;
	nv.x = v.x * value;
	nv.y = v.y * value;
	nv.z = v.z * value;
	return nv;
}
Vector3 operator / (Vector3 &v, real value)
{
	Vector3 nv;
	nv.x = v.x / value;
	nv.y = v.y / value;
	nv.z = v.z / value;
	return nv;
}
real Vector3::DotProduct(Vector3 &v1, Vector3 &v2)
{
	return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
Vector3 Vector3::CrossProduct(Vector3 &v1, Vector3 &v2)
{
	Vector3 v;
	v.x = v1.y * v2.z - v1.z * v2.y;
	v.y = v1.z * v2.x - v1.x * v2.z;
	v.z = v1.x * v2.y - v1.y * v2.x;
	return v;
}
real Vector3::Length()
{
	return sqrt(PoweredLength());
}
real Vector3::PoweredLength()
{
	return x * x + y * y + z * z;
}

Vector3& Vector3::Normalize(void)
{
	real d = Length();
	x /= d;
	y /= d;
	z /= d;
	return *this;
}

void Vector3::Add(Vector3 &result, Vector3 &v1, Vector3 &v2)
{
	result.x = v1.x + v2.x;
	result.y = v1.y + v2.y;
	result.z = v1.z + v2.z;
}
void Vector3::Subtract(Vector3 &result, Vector3 &v1, Vector3 &v2)
{
	result.x = v1.x - v2.x;
	result.y = v1.y - v2.y;
	result.z = v1.z - v2.z;
}
void Vector3::Multiply(Vector3 &result, Vector3 &v, real value)
{
	result.x = v.x * value;
	result.y = v.y * value;
	result.z = v.z * value;
}
void Vector3::Multiply(Vector3 &result, real value, Vector3 &v)
{
	result.x = v.x * value;
	result.y = v.y * value;
	result.z = v.z * value;
}
void Vector3::Divide(Vector3 &result, Vector3 v, real value)
{
	result.x = v.x / value;
	result.y = v.y / value;
	result.z = v.z / value;
}
Vector3 Vector3::Normalized(Vector3 &v)
{
	Vector3 nv;
	nv.x = v.x;
	nv.y = v.y;
	nv.z = v.z;
	return nv.Normalize();
}

void Vector3::Normalized(Vector3 &result, Vector3 &v)
{
	result.x = v.x;
	result.y = v.y;
	result.z = v.z;
	result.Normalize();
}
Vector3 Vector3::Interpolate(Vector3 &v1, Vector3 &v2, real t)
{
	return v1 * (1 - t) + v2 * t;
}
void Vector3::Interpolate(Vector3 &result, Vector3 &v1, Vector3 &v2, real t)
{
	result = v1 * (1 - t) + v2 * t;
}

//************** Vector2 *********************************************

Vector2::Vector2()
{	
}
Vector2::Vector2(const Vector2 &vector)
{
	x = vector.x;
	y = vector.y;	
}
Vector2::Vector2(real x, real y)
{
	this->x = x;
	this->y = y;	
}

Vector2& Vector2::operator = (Vector2 &v)
{
	x = v.x;
	y = v.y;	
	return *this;
}
Vector2 operator + (Vector2 &v1, Vector2 &v2)
{
	Vector2 v;
	v.x = v1.x + v2.x;
	v.y = v1.y + v2.y;	
	return v;
}

Vector2 operator - (Vector2 &v1, Vector2 &v2)
{
	Vector2 v(v1);
	v.x = v1.x - v2.x;
	v.y = v1.y - v2.y;	
	return v;
}
Vector2& Vector2::operator *= (real value)
{
	x *= value;
	y *= value;	
	return *this;
}
Vector2& Vector2::operator /= (real value)
{
	x /= value;
	y /= value;	
	return *this;
}
Vector2& Vector2::operator += (Vector2 &v)
{
	x += v.x;
	y += v.y;	
	return *this;
}
Vector2& Vector2::operator -= (Vector2 &v)
{
	x -= v.x;
	y -= v.y;	
	return *this;
}

Vector2 operator * (Vector2 &v, real value)
{
	Vector2 nv;
	nv.x = v.x * value;
	nv.y = v.y * value;	
	return nv;
}
Vector2 operator * (real value,Vector2 &v)
{
	Vector2 nv;
	nv.x = v.x * value;
	nv.y = v.y * value;	
	return nv;
}
Vector2 operator / (Vector2 &v, real value)
{
	Vector2 nv;
	nv.x = v.x / value;
	nv.y = v.y / value;	
	return nv;
}
real Vector2::DotProduct(Vector2 &v1, Vector2 &v2)
{
	return v1.x * v2.x + v1.y * v2.y;
}
real Vector2::Length()
{
	return sqrt(PoweredLength());
}
real Vector2::PoweredLength()
{
	return x * x + y * y;
}

Vector2& Vector2::Normalize(void)
{
	real d = Length();
	x /= d;
	y /= d;	
	return *this;
}

void Vector2::Add(Vector2 &result, Vector2 &v1, Vector2 &v2)
{
	result.x = v1.x + v2.x;
	result.y = v1.y + v2.y;
}
void Vector2::Subtract(Vector2 &result, Vector2 &v1, Vector2 &v2)
{
	result.x = v1.x - v2.x;
	result.y = v1.y - v2.y;
}
void Vector2::Multiply(Vector2 &result, Vector2 &v, real value)
{
	result.x = v.x * value;
	result.y = v.y * value;
}
void Vector2::Multiply(Vector2 &result, real value, Vector2 &v)
{
	result.x = v.x * value;
	result.y = v.y * value;
}
void Vector2::Divide(Vector2 &result, Vector2 v, real value)
{
	result.x = v.x / value;
	result.y = v.y / value;
}
Vector2 Vector2::Normalized(Vector2 &v)
{
	Vector2 nv;
	nv.x = v.x;
	nv.y = v.y;
	return nv.Normalize();
}

void Vector2::Normalized(Vector2 &result, Vector2 &v)
{
	result.x = v.x;
	result.y = v.y;
	result.Normalize();
}
Vector2 Vector2::Interpolate(Vector2 &v1, Vector2 &v2, real t)
{
	return v1 * (1 - t) + v2 * t;
}
void Vector2::Interpolate(Vector2 &result, Vector2 &v1, Vector2 &v2, real t)
{
	result = v1 * (1 - t) + v2 * t;
}